/**
 *
 */
package club.pinea.util;

import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

/**
 * 用来生成protobuf
 *
 * @author admin
 *
 */
public class ProtoGenerareUtil {

    static String root = "";
    // proto文件地址
    static String proto_dir = "";
    // protoc可执行文件路径
    static String protoExe = "";
    //生成pojo类地址
    static String pojo_dir = "";

    static String protoc_cmd = protoExe + " -I=" + proto_dir + " --java_out=" + root + "/src/main/java" + " --cpp_out=" + root + "C " + proto_dir + File.separator;

    static String commonXml = "";

    static {
        File file = new File(ProtoGenerareUtil.class.getClass().getResource("/").getPath());
        root = file.getParentFile().getParentFile().getAbsolutePath() + File.separator;
        proto_dir = root + "src/main/resources/protos";
        protoExe = root + "lib/protoc-3.2.0-win32/bin/protoc.exe";
//		protoExe = "protoc";
        pojo_dir = root + "/src/main/java/club/pinea/proto";
        commonXml = root + File.separator + "src/main/resources/" + "common.xml";
    }

    static String format_proto_cmd(File f) {
        String cmd = protoExe;
        cmd += (" -I=" + f.getParent());
        cmd += (" --java_out=" + root + "src/main/java");
//        cmd += (" --cpp_out=" + root + "C");
//        cmd += (" --js_out=" + root + "js");
        cmd += (" " + f.getAbsolutePath());
        return cmd;
    }

    static void proto_path(File protoDir, List<File> listProto) {
        System.out.println("proto path:" + protoDir.getName());
        Runtime rt = Runtime.getRuntime();
        for (File f : protoDir.listFiles()) {
            try {
                if (f.isDirectory()) {
                    proto_path(f, listProto);
                } else {
                    if (!f.getName().endsWith(".proto")) continue;
                    String cmd = format_proto_cmd(f);
                    System.out.println(cmd);
                    Process pr = rt.exec(cmd);
                    BufferedReader input = new BufferedReader(new InputStreamReader(pr.getErrorStream()));
                    String line = null;
                    while ((line = input.readLine()) != null) {
                        System.out.println(line);
                    }
                    int exitVal = pr.waitFor();
                    System.out.println("Exited with error code " + exitVal);
                    listProto.add(f);
                }
            } catch (Exception e) {
                System.out.println(e.toString());
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        //删除原来生成的文件
        File pojoDir = new File(pojo_dir);
        if (pojoDir.exists()) {
            deleteDir(pojoDir);
        }

        File protoDir = new File(proto_dir);
        if (!protoDir.exists() || !protoDir.isDirectory()) {
            System.out.println(proto_dir + "不存在或者不是目录");
            return;
        }

        File cPath = new File(root + File.separator + "C");
        if (cPath.exists()) {
            deleteDir(cPath);
        }

        if (!cPath.exists()) {
            cPath.mkdirs();
        }

        List<File> listProto = new ArrayList<>();
        proto_path(protoDir, listProto);
//		CreateCommon.createCommon(listProto, commonXml);
    }

    /**
     * 递归删除目录下的所有文件及子目录下所有文件
     *
     * @param dir
     *            将要删除的文件目录
     * @return boolean Returns "true" if all deletions were successful. If a
     *         deletion fails, the method stops attempting to delete and returns
     *         "false".
     */
    private static boolean deleteDir(File dir) {
        if (dir.isDirectory()) {
            String[] children = dir.list();
            // 递归删除目录中的子目录下
            for (int i = 0; i < children.length; i++) {
                boolean success = deleteDir(new File(dir, children[i]));
                if (!success) {
                    return false;
                }
            }
        }
        // 目录此时为空，可以删除
        boolean flag = dir.delete();
        System.out.println("删除文件【" + dir.getName() + "】:" + flag);
        return flag;
    }
}
